

const zlib = require('zlib');


const unzipBuff = (buffer, cb) => {
	zlib.unzip(buffer, (err, buffer) => {
		if (!err) {
			cb && cb(buffer.toString())
		}
	});
} 


var mysocket = function(connection, opts) {
	this.connection = connection;
	this.listeners = {
		'onopen':{},
		'onclose':{},
		'onerror':{},
		'onmessage':{},
		'events':{},
	};
	this.isOpen = false
	this.opts = Object.assign({},opts);
}
mysocket.prototype.close = function () {
	if (this.$socket) {
		this.$socket.close()
	}
}
//连接
mysocket.prototype.conn = function(connection) {
	if (connection) {
		connection = this.connection +=  connection;
	} else {
		connection = this.connection
	}
	
	
	if (!this.$socket) {
		if (typeof WebSocket == 'undefined') {
			console.error('当前浏览器不支持websocket');
			return false;
		}

		if (!connection) {
			console.error('[mysocket] cannot locate connection');
			return false;
		}
		this.$socket = new WebSocket(connection);
		
		this.$socket.onopen = (e) => {
			this.isOpen = true
			this.call('onopen',e);
		};
		this.$socket.onmessage = (e) => {
			if (e.data) {
				var buffer = new Buffer(e.data, 'base64');
				unzipBuff(buffer, (res) => {
					this.call('onmessage',JSON.parse(res));
				})
				
			}
			
		};

		this.$socket.onclose = (e) => {
			this.$socket = null
			this.call('onclose',e);
		};
		
		this.$socket.onerror = (e) => {
			this.call('onclose',e);
		}
	}
	return true;
}

mysocket.prototype.send = function(data){
	if( typeof(data)=='object' ){
		data = JSON.stringify(data);
	}
	this.$socket.send(data);
}

mysocket.prototype.call = function(type,data){
	if( typeof(data)=='string' ){
		data = JSON.parse(data)||{};
	}

	if( type=='onmessage' && data.event ){
		if(data.event && data.data && this.listeners['events'] && this.listeners['events'][data.event] ){
			let events = this.listeners['events'][data.event];
			Object.keys( events ).forEach((_uid) =>
			{
				events[_uid](data.data);
			});
		}
	}

	if( this.listeners[type][type] )
	{
		Object.keys(this.listeners[type][type]).forEach((event) =>
		{
			this.listeners[type][type][event](data);
		});
	}
}

//添加监听
mysocket.prototype.addListeners = function(type, funcname,_uid,func) {
	if( typeof(func)=='function' ){
		if( !this.listeners[type][funcname] ){
			this.listeners[type][funcname] = {};
		}
		this.listeners[type][funcname][_uid] = func;
	}
}

//移除监听
mysocket.prototype.removeListeners = function(type, funcname,_uid) {
	if( this.listeners[type] && this.listeners[type][funcname] && this.listeners[type][_uid] ){
		delete this.listeners[type][funcname][_uid];
	}
}


export default {
	install(Vue, connection, opts) {
		let socket = new mysocket(connection, opts);
		let addListeners = function() {
			if (this.$options['socket']){
				let binds = this.$options['socket'];
				Object.keys( binds ).forEach((type) => {
					if( type=='events' ){
						Object.keys( binds['events'] ).forEach((event) =>
						{
							if( typeof(binds['events'][event])=='function' ){
								socket.addListeners('events',event,'_'+this._uid,binds['events'][event].bind(this));
							}
						});
					}else{
						if( typeof(binds[type])=='function' ){
							socket.addListeners(type ,type,'_'+this._uid ,binds[type].bind(this) );
						}
					}
				});
			}

		};
		let removeListeners = function() {
			if (this.$options['socket']){
				let binds = this.$options['socket'];
				Object.keys( binds ).forEach((type) => {
					if( type=='events' ){
						Object.keys( binds['events'] ).forEach((event) =>
						{
							socket.removeListeners('events',event,'_'+this._uid);
						});
					}else{
						socket.removeListeners(type,event,'_'+this._uid);
					}
				});
			}
		};
		Vue.mixin({
			[Vue.version.indexOf("2") === 0 ? "beforeCreate" : "beforeCompile"]: addListeners,
			beforeDestroy: removeListeners
		});
		
		Vue.prototype.$socket = socket;
	}
}
